/*!
 * KASlider.js
 */
var KASlider = function(settings) {
    this.range = settings.range;
    this.route = settings.route;
    this.bar = settings.bar;
    this.settings = jQuery.extend({
        progress: 0,// Range[0..1]
        overflow: true,
        onClick: null,
        onMouseDown: null,
        onMoveStart: null,
        onMoveEnd: null,
        onMouseUp: null
    }, settings);
    this.initialize();
};
// Initialize
KASlider.prototype.initialize = function() {
    var length = 0;
    var that = this;
    this.moveTo(this.settings.progress);

    this.range.click(function(evt) {
        that.settings.progress = ((evt || event).clientX - $(this).offset().left)/$(this).width();
        that.moveTo(that.settings.progress);
        if (typeof(that.settings.onClick) == "function") {
            that.settings.onClick(that.settings);
        }
    });

    this.bar.click(function(evt) {
        if (window.event) {
            window.event.cancelBubble = true;
        } else {
            (evt || event).stopPropagation();
        }
    });

    this.bar.mousedown(function(evt) {
        if (typeof(that.settings.onMouseDown) == "function") {
            if (!that.settings.onMouseDown(that.settings)) {
                return;
            }
        }

        length = (evt || event).clientX - $(this).position().left;
        that.bar.setCapture ? (
            that.bar.setCapture(),
            that.bar.onmousemove = function(e) {
                mouseMove(e || event);
            },
            that.bar.onmouseup = mouseUp
        ) : (
            $(document).bind("mousemove", mouseMove).bind("mouseup", mouseUp)
        );
    });

    function mouseMove(evt) {
        if (typeof(that.settings.onMoveStart) == "function") {
            if (!that.settings.onMoveStart(that.settings)) {
                return;
            }
        }

        if (that.settings.overflow) {
            if (evt.clientX - length <= -that.bar.width()/2) {
                that.bar.css("left", -that.bar.width()/2 + "px");
            } else if (evt.clientX - length + that.bar.width()/2 >= that.range.width()) {
                that.bar.css("left", that.range.width() - that.bar.width()/2 + "px");
            } else {
                that.bar.css("left", evt.clientX - length + "px");
            }
            that.route.width(parseInt(that.bar.css("left")) + that.bar.width()/2);
        } else {
            if (evt.clientX - length <= 0) {
                that.bar.css("left", "0");
            } else if (evt.clientX - length + that.bar.width() >= that.range.width()) {
                that.bar.css("left", that.range.width() - that.bar.width() + "px");
            } else {
                that.bar.css("left", evt.clientX - length + "px");
            }
            that.route.width(parseInt(that.bar.css("left"))*that.range.width()/(that.range.width() - that.bar.width()));
        }

        that.settings.progress = that.route.width()/that.range.width();
        if (typeof(that.settings.onMoveEnd) == "function") {
            that.settings.onMoveEnd(that.settings);
        }
    }

    function mouseUp() {
        that.setCapture ? (
            that.bar.releaseCapture(),
            that.bar.onmousemove = that.bar.onmouseup = null
        ) : (
            $(document).unbind("mousemove", mouseMove).unbind("mouseup", mouseUp)
        );
        if (typeof(that.settings.onMouseUp) == "function") {
            that.settings.onMouseUp(that.settings);
        }
    }
};
// Move To
KASlider.prototype.moveTo = function(progress) {
    if (typeof(this.settings.onMoveStart) == "function") {
        if (!this.settings.onMoveStart(this.settings)) {
            return;
        }
    }

    if (isNaN(progress)) {
        return;
    }
    progress = progress < 0 ? 0 : (progress > 1 ? 1 : progress);

    if (this.settings.overflow) {
        this.bar.css("left", this.range.width()*progress - this.bar.width()/2 + "px");
    } else {
        this.bar.css("left", (this.range.width() - this.bar.width())*progress + "px");
    }
    this.route.width(this.range.width()*progress);

    this.settings.progress = progress;
    if (typeof(this.settings.onMoveEnd) == "function") {
        this.settings.onMoveEnd(this.settings);
    }
};
